#include "server_socket.h"

/**
 * 判断fd是否有效
 */
static int isvalid(int fd)
{
	return fd != INVALID_SOCKET;
}

/**
 * 创建 socket fd
 * @param  ip   [ip地址]
 * @param  port [端口号]
 * @return      [返回sock fd]
 */
int create_connect_socket(const char *ip, const short port)
{
	int client_sockfd;   

	struct sockaddr_in remote_addr; 				//服务器端网络地址结构体  

	memset(&remote_addr, 0, sizeof(remote_addr)); 	//数据初始化--清零  
	remote_addr.sin_family = AF_INET; 				//设置为IP通信  
	remote_addr.sin_addr.s_addr = inet_addr(ip);	//服务器IP地址  
   	remote_addr.sin_port = htons(port); 			//服务器端口号  
     
 
	if((client_sockfd = socket(PF_INET, SOCK_STREAM, 0))<0)  
		return -1;
		
	 
   	/*将套接字绑定到服务器的网络地址上*/  
	if(connect(client_sockfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr)) < 0)  
		return -1;  
	
	
	return client_sockfd;
}

/**
 * 发送消息给服务端
 * @param s [description]
 */
void server_send(session *s)
{
	int len = send(s->fds[SOCKET_FD], s->buf, s->bsize, 0);  
	s->bsize = len;
}

/**
 * 接收服务端消息
 * @param s [保存服务端消息和长度]
 */
void server_recv(session *s)
{
	int len = recv(s->fds[SOCKET_FD], s->buf, s->msize, 0);  
	s->bsize = len;
}

/**
 * 对 session 进行初始化 
 * @param s       [description]
 * @param connfd  [description]
 * @param stdinfd [description]
 */
void init_socket_server(session *s, int connfd, int stdinfd)
{
	int i;
	for(i = 0; i< FDMAX; i++)
	{
		s->fds[i] = INVALID_SOCKET;
	}

	bzero(s->buf, sizeof(s->buf));
	
	int efd = event_create();
	
	s->fds[EPOLL_FD] = efd;		//fds[0] is epoll_create() return fd
	s->fds[SOCKET_FD] = connfd;		//fds[1] is service fd
	s->fds[STDIN_FD] = stdinfd;
	
	s->bsize = BUFMAX;
	s->msize = BUFMAX;
	
	event_add(efd, connfd, EPOLLIN);
	event_add(efd, stdinfd, EPOLLIN);		

}

/**
 * epoll 等待消息得来
 * @param  s [客户端会话对象]
 * @return   [返回消息类型]
 */
int server_wait(session *s)
{
	struct epoll_event e[FDMAX];
	int n = event_wait(s->fds[EPOLL_FD], e, FDMAX);
		
	bzero(s->buf, s->msize);
	
	int i;
	for(i = 0; i < n; i++)
	{
		int fd = e[i].data.fd;
		int events = e[i].events;
		
		if(!isvalid(fd))
			continue;
		
		//stdin 读事件到来
		if((fd == s->fds[STDIN_FD]) && (events & EPOLLIN))
		{
			s->bsize = read(fd, s->buf, s->msize);
			s->buf[s->bsize - 1] = 0;
			
			return STDIN_DATA;
		}
		//socket fd读事件到来
		else if((fd == s->fds[SOCKET_FD]) && (events & EPOLLIN))
		{
			return SOCKET_DATA;
		}
		
	}

	return -1;
}



